#include "Reg52.h"
#include "uart.h"
#include "types.h"
#include "net.h"
#include "cmd.h"
#include "smi.h"
#include "time.h"

#define	UART_MAX_BUF	16
#define	UART_MAX_MASK	(UART_MAX_BUF - 1)

static uint8_t uart_recv_buf[UART_MAX_BUF];
static uint8_t uart_recvpt = 0;
static uint8_t uart_recvwt = 0;

#define	UART_PUT(d)	do {uart_recv_buf[uart_recvpt++] = d; uart_recvpt &= UART_MAX_MASK;} while (0)
#define	UART_GET(d)	do {d = uart_recv_buf[uart_recvwt++]; uart_recvwt &= UART_MAX_MASK;} while (0)
#define	UART_SKIP(d)	do {uart_recvwt += d; uart_recvwt &= UART_MAX_MASK;} while (0)
#define	UART_SIZE	((uart_recvpt - uart_recvwt) & UART_MAX_MASK)
#define	UART_FULL	(((uart_recvpt + 1) & UART_MAX_MASK) == uart_recvwt)
#define	UART_CLEAR	(uart_recvpt = uart_recvwt = 0)

void uart_interrupt(void) interrupt 4
{ 
  	if (RI) { 
    		RI = 0;
		if (!UART_FULL)
			UART_PUT(SBUF);
    	}
	
  	if (TI)
    		TI = 0;
}

void uart_send_byte(unsigned char byte)
{
	while (TI);

	SBUF = byte;
	msdelay(10);
}

#if 0
void uart_send_str(char *s)
{
	while (*s != 0) {
		uart_send_byte(*s++);
	}
}
#endif

void uart_init(void)
{
 	SCON = 0x50;

  	RI = 0;
  	TI = 0;	
  	ES = 1;
}

void polling_uart(void)
{
	uint8_t cmd, id, reg, phy;
	uint16_t value;

	if (UART_SIZE < sizeof(struct cmd))
		return;

	if (uart_recv_buf[0] != CMD_START1)
		goto out;

	if (uart_recv_buf[1] != CMD_START2)
		goto out;

	cmd = uart_recv_buf[2];
	id  = uart_recv_buf[3];
	phy = uart_recv_buf[4];
	reg = uart_recv_buf[5];

	if (uart_recv_buf[2] == CMD_R) {
		value = smi_read(id, phy, reg);
		uart_send_byte(CMD_START1);
		uart_send_byte(CMD_START2);
		uart_send_byte(value >> 8);
		uart_send_byte(value & 0xFF);
		goto out;
	}

	if (UART_SIZE < sizeof(struct cmd) + 2)
		return;

	value = uart_recv_buf[6] << 8 | uart_recv_buf[7];
	smi_write(id, phy, reg, value);
	uart_send_byte(CMD_START1);
	uart_send_byte(CMD_START2);
	uart_send_byte(0x00);

out:
	UART_CLEAR;
}
